﻿using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using UnityEngine;
using System.Text;
using System.IO;

public class CharConvert
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
	static char[] cache = new char[1024];

	//把GB2312转成UNCODE码,返回MemoryStream.
	public static MemoryStream GB2312ToUnicodeEx(byte[] src, int offset = 0, int length = -1)
	{
		char[] exCache = new char[src.Length];
		unsafe
		{
			fixed (byte* pDes = &src[offset])
			{
				fixed (char* pSrc = &exCache[0])
				{
					int len = length > 0 ? length : src.Length;
					
					int res = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pDes, len, pSrc, exCache.Length);

					byte[] result = Encoding.UTF8.GetBytes(exCache, 0, res);

					return new MemoryStream(result);
				}
			}
		}
	}

	//把GB2312转成UNCODE码,返回string.
	public static string GB2312ToUnicode(byte[] src, int offset = 0, int length = -1)
	{
		unsafe
		{
			fixed (byte* pDes = &src[offset])
			{
				fixed (char* pSrc = &cache[0])
				{
					int len = length > 0 ? length : src.Length;
					
					int res = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pDes, len, pSrc, cache.Length);
					
					return new string(cache, 0, res);
				}
			}
		}
	}
	
	protected const uint CP_ACP = 0;
	protected const uint MB_PRECOMPOSED = 1;

	[DllImport("kernel32.dll", SetLastError = true)]
    public static extern unsafe int MultiByteToWideChar
	(
		uint CodePage, 
		uint dwFlags,         
		byte* lpMultiByteStr, 
		int cbMultiByte,       
		char* lpWideCharStr,  
		int cchWideChar        
	);
#endif

	//string转object.
	public static object Format(string str, Type type)
	{
		if(string.IsNullOrEmpty(str))
		{
			return null;
		}

		if(type == null)
		{
			return str;
		}

		if(type.IsArray)
		{
			Type elementType = type.GetElementType();
			string[] strs = str.Split('|');
			Array array = Array.CreateInstance(elementType, strs.Length);
			for(int i = 0; i < strs.Length; i++)
			{
				array.SetValue(StringConvertType(strs[i], elementType), i);
			}

			return array;
		}

		return StringConvertType(str, type);
	}

	//unity3d中的类型转换.
	private static object StringConvertType(string str, Type type)
	{
		object res = null;
		if(type == typeof(Vector2))
		{
			res = UniTool.StringToVector2(str);
		}
		else if(type == typeof(Vector3))
		{
			res = UniTool.StringToVector3(str);
		}
		else if(type == typeof(Vector4))
		{
			res = UniTool.StringToVector4(str);
		}
		else if(type == typeof(Color))
		{
			res = UniTool.StringToColor(str);
		}
		else if(type == typeof(Color32))
		{
			res = UniTool.StringToColor32(str);
		}
		else 
		{
			res = ConvertSimpleType(str, type);
		}

		if(res == null && type.IsValueType)
		{
			res = System.Activator.CreateInstance(type);
		}

		return res;
	}

	//.net默认的类型转换.
	private static object ConvertSimpleType(object value, Type destinationType)
	{
		object returnValue;
		if ((value == null) || destinationType.IsInstanceOfType(value))
		{
			return value;
		}
		string str = value as string;
		if ((str != null) && (str.Length == 0))
		{
			return null;
		}
		TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
		bool flag = converter.CanConvertFrom(value.GetType());
		if (!flag)
		{
			converter = TypeDescriptor.GetConverter(value.GetType());
		}
		if (!flag && !converter.CanConvertTo(destinationType))
		{
			throw new InvalidOperationException("无法转换成类型：" + value.ToString() + "==>" + destinationType);
		}

		try
		{
			returnValue = flag ? converter.ConvertFrom(null, null, value) : converter.ConvertTo(null, null, value, destinationType);
		}
		catch (Exception e)
		{
			throw new InvalidOperationException("类型转换出错：" + value.ToString() + "==>" + destinationType, e);
		}
		return returnValue;
	}
	
}
